package cn.tedu.csmall.resource.controller;

import cn.tedu.csmall.commons.ex.ServiceException;
import cn.tedu.csmall.resource.pojo.vo.UploadResult;
import cn.tedu.csmall.commons.web.JsonResult;
import cn.tedu.csmall.commons.web.ServiceCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 处理文件上传的控制器类
 */
@Slf4j
@RestController
@RequestMapping("/resource")
@Api(tags = "文件上传模块")
public class ResourceController {

    /**
     * 上传的主机地址
     */
    @Value("${csmall.upload.host}")
    private String host;
    /**
     * 上传的根路径
     */
    @Value("${csmall.upload.base-dir}")
    private String uploadBaseDir;
    /**
     * 商品图片大小
     */
    @Value("${csmall.upload.product-image.max-size}")
    private Integer productImageMaxSize;
    /**
     * 上传图片的类型
     */
    @Value("${csmall.upload.product-image.types}")
    private List<String> productImageValidTypes;

    /**
     * 保存商品图片的文件夹路径
     */
    private String productImagePath = "product-image/";
    /**
     * 保存商品图片的时间路径
     */
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");

    public ResourceController() {
        log.debug("创建控制器类对象：ResourceController");
    }

    @PostMapping("/upload/image/product")
    @ApiOperation("上传商品图片")
    public JsonResult uploadProductImage(@RequestParam("file") MultipartFile multipartFile) throws IOException {

        // 判断上传文件是否为空
        if (multipartFile == null || multipartFile.isEmpty()) {
            String message = "上传商品图片失败，请选择您要上传的文件！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_UPLOAD_EMPTY, message);
        }

        // 获取文件大小
        long size = multipartFile.getSize();
        if (size > productImageMaxSize * 1024 * 1024) {
            String message = "上传商品图片失败，不允许使用超过" + productImageMaxSize + "MB的图片文件！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_UPLOAD_EXCEED_MAX_SIZE, message);
        }

        // 检查图片类型
        String contentType = multipartFile.getContentType();
        if (!productImageValidTypes.contains(contentType)) {
            String message = "上传商品图片失败，请使用以下类型的图片文件：" + productImageValidTypes;
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPLOAD_INVALID_TYPE, message);
        }

        // 准备一个和日期相关的路径
        String datePath = simpleDateFormat.format(new Date());
        // File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。
        File productImageDir = new File(uploadBaseDir, productImagePath);
        // 上传路径
        File uploadDir = new File(productImageDir, datePath);
        System.out.println("uploadDir=" + uploadDir);

        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }

        // 得到唯一文件名
        String newFileName = UUID.randomUUID().toString();
        // 得到文件的原始文件名
        String originalFilename = multipartFile.getOriginalFilename();
        // 得到文件的后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        // 得到唯一文件名
        String fileName = newFileName + suffix;
        // 用【上传路径】和【文件名】创建新的File实例
        File newFile = new File(uploadDir, fileName);
        //把接收到的文件保存在这个路径中
        multipartFile.transferTo(newFile);

        System.out.println("newFile=" + newFile);

        String url = new StringBuilder()
                .append(host)                 // 对外访问的主机
                .append(productImagePath)     // 保存商品图片的文件夹路径
                .append(datePath + "/")       // 保存商品图片的时间路径
                .append(fileName)             // 文件名
                .toString();

        UploadResult uploadResult = new UploadResult();
        uploadResult.setUrl(url);
        uploadResult.setFileSize(size);
        uploadResult.setContentType(contentType);
        uploadResult.setFileName(fileName);
        uploadResult.setImageName(fileName);
        return JsonResult.ok(uploadResult);
    }


}
